use alice2d::{ui::egui::{Context, Ui, self, Id, DragValue, Color32, Stroke, Rounding, TextureHandle}, ecs::entity, scene::{TagComponent, TransformComponent, CameraComponent, SpriteRendererComponent, Rigidbody2DComponent, Collider2DComponent, Entity, ScriptComponent, SceneServer, Scene}, math::Vector3f, color::Rgba};

use crate::editor::EditorLayer;


const DELETE_BUTTON_WIDTH:f32 = 60.0;

const LABEL_WIDTH: f32 = 60.0;



pub struct InspectPanel;


impl InspectPanel {
    pub fn draw_inspector(layer:&mut EditorLayer, ctx: &mut Context) {
        let server = SceneServer::get_server_mut();
        let scene = server.get_active_scene_mut();
        alice2d::ui::egui::SidePanel::right("inspect_panel")
            .resizable(true)
            .default_width(400.0)
            .width_range(80.0..=450.0)
            .show(ctx, |ui| {
                ui.vertical_centered(|ui| {
                    ui.heading("Inspect Panel");
                });
                if let Some(entity) = &layer.select_entity {
                  
                    Self::draw_node_inspector(layer,*entity,scene, ui);
                }
            });
    }

    fn draw_node_inspector(layer:&mut EditorLayer, handle: entity::Entity,scene:&mut Scene, ui: &mut Ui) {
        if let Some(mut entity_mut) = scene.world.get_entity_mut(handle) {

            

            if let Some(mut tag) = entity_mut.get_mut::<TagComponent>() {
                alice2d::ui::egui::Grid::new("name").show(ui, |ui| {
                    egui::Grid::new("my_grid")
                    .num_columns(2)
                    .spacing([40.0, 4.0])
                    .striped(true)
                    .show(ui, |ui| {
                        ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("name"));
                        ui.add(egui::TextEdit::singleline(&mut tag.tag).hint_text("Write something here"));
                    });
                 
           
                });
            }

            if  entity_mut.contains::<TransformComponent>() {
                let mut  removed = false;
                ui.horizontal(|ui|{
      
                    let size = ui.available_width() - DELETE_BUTTON_WIDTH;
                        ui.spacing_mut().item_spacing.x = 3.0;
                        ui.add_sized([size, 20.0], alice2d::ui::egui::Button::new("Transform"));
                        if ui.button("delete").clicked() {
                            removed = true;
                            entity_mut.remove::<TransformComponent>();
                        }
                });
              
                if !removed {
                    ui.scope(|ui|{
                        let mut transform = entity_mut.get_mut::<TransformComponent>().unwrap();
                        let position = &mut transform.translation;
                        draw_vec3_control(ui, "position", position, 0.0, 0.0);
    
                        let rotation = &mut transform.rotation;
                        draw_vec3_control(ui, "rotation", rotation, 0.0, 0.0);
    
                        let scale = &mut transform.scale;
                        draw_vec3_control(ui, "scale", scale, 1.0, 10.0);
                    });
                }

             

                ui.end_row();
            }

            if  entity_mut.contains::<CameraComponent>() {
                let mut removed = false;
                ui.horizontal(|ui|{
      
                    let size = ui.available_width() - DELETE_BUTTON_WIDTH;
                    ui.spacing_mut().item_spacing.x = 3.0;
                    ui.add_sized([size, 20.0], alice2d::ui::egui::Button::new("Camera"));
                    if ui.button("delete").clicked() {
                        removed = true;
                        entity_mut.remove::<CameraComponent>();
                    };
                });
              
                if !removed {
                    ui.scope(|ui|{
                        let mut camera = entity_mut.get_mut::<CameraComponent>().unwrap();
    
                        alice2d::ui::egui::Grid::new("primary camera")
                        .min_row_height(20.0)
                        .spacing([43.0, 4.0])
                        .striped(true)
                        .show(ui, |ui| {
                            ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("primary camera"));
                            
                            if ui.checkbox(&mut camera.primary, "").changed() {
                                if camera.primary {
                                    scene.primary_camera = Some(handle)
                                }else{
                                    if let Some(primary_camera) = scene.primary_camera {
                                        if handle == primary_camera {
                                            scene.primary_camera = None;
                                        }
                                    }
                                }
                             
                            }
                          
                        
                        });

                        alice2d::ui::egui::Grid::new("camera type")
                        .min_row_height(20.0)
                        .spacing([43.0, 4.0])
                        .striped(true)
                        .show(ui, |ui| {
                            ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("type"));
                            
                            alice2d::ui::egui::ComboBox::from_id_source("select camera")
                            .selected_text(format!("{:?}", camera.camera_ty))
                            .show_ui(ui, |ui| {
                                ui.selectable_value(&mut camera.camera_ty, alice2d::scene::CameraType::Orthographic, "Orthographic");
                                ui.selectable_value(&mut camera.camera_ty, alice2d::scene::CameraType::Perspective, "Perspective");
                               }
                            );
                          
                        
                        });
                        match camera.camera_ty {
                            alice2d::scene::CameraType::Orthographic => {
                                alice2d::ui::egui::Grid::new("viewport size")
                                .min_row_height(20.0)
                                .spacing([43.0, 4.0])
                                .striped(true)
                                .show(ui, |ui| {
                                    ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("viewport size"));
                                    DragValue::new( &mut camera.orthographic_size)
                                });
                                
                            },
                            alice2d::scene::CameraType::Perspective => {
                                alice2d::ui::egui::Grid::new("fovy")
                                .min_row_height(20.0)
                                .spacing([43.0, 4.0])
                                .striped(true)
                                .show(ui, |ui| {
                                    ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("fovy"));
                                    let mut angle = camera.perspective_fovy.to_degrees();
                                    ui.add(DragValue::new( &mut angle).clamp_range(0.0..=180.0).fixed_decimals(1).speed(1.0));
                                    camera.perspective_fovy = angle.to_radians();
                                });
    
                                alice2d::ui::egui::Grid::new(Id::new("clip")).show(ui, |ui| {
                                    ui.style_mut().spacing.item_spacing.x = 20.0;
                            
                                    ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("clip"));
                            
                                    ui.spacing_mut().indent = 0.0;
                                    ui.horizontal(|ui| {
                          
                            
                                        ui.style_mut().spacing.button_padding.x = 10.0;
                            
                                        let color = alice2d::ui::egui::Color32::from_rgba_premultiplied(25, 29, 38, 255);
                                        set_bg(ui, color, color, color);
                            
                                        ui.scope(|ui| {
                                            ui.style_mut().spacing.item_spacing.x = 0.0;
                            
                                            ui.scope(|ui| {
                                                ui.visuals_mut().override_text_color =
                                                    Some(alice2d::ui::egui::Color32::from_rgba_premultiplied(228, 152, 5, 255));
                            
                                                if ui.button("near").clicked() {
                                                    camera.clip_near = 0.1;
                                                }
                                            });
                            
                                            let color = alice2d::ui::egui::Color32::from_rgba_premultiplied(32, 36, 48, 255);
                                            set_bg(ui, color, color, color);
                            
                                            ui.spacing_mut().interact_size.x = 60.0;
                                            ui.add(DragValue::new(&mut camera.clip_near).speed(1.0));
                                        });
                            
                                        ui.scope(|ui| {
                                            ui.style_mut().spacing.item_spacing.x = 0.0;
                            
                                            ui.scope(|ui| {
                                                ui.visuals_mut().override_text_color =
                                                    Some(alice2d::ui::egui::Color32::from_rgba_premultiplied(33, 145, 232, 255));
                            
                                                if ui.button("far").clicked() {
                                                    camera.clip_far = 1000.0;
                                                }
                                            });
                                            let color = alice2d::ui::egui::Color32::from_rgba_premultiplied(32, 36, 48, 255);
                                            set_bg(ui, color, color, color);
                                            ui.spacing_mut().interact_size.x = 60.0;
                                            ui.add(DragValue::new(&mut camera.clip_far).speed(0.1));
                                        });
                            
                                
                                    });
                                    ui.end_row();
                                });
    
                                alice2d::ui::egui::Grid::new("aspect")
                                .min_row_height(20.0)
                                .spacing([43.0, 4.0])
                                .striped(true)
                                .show(ui, |ui| {
                                    ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("aspect"));
                         
                                    ui.add(DragValue::new( &mut camera.aspect_ratio).fixed_decimals(2).speed(1.0));
               
                                });
    
                                
                            },
                        }
    
                        
                    });
    
                }
         
                ui.end_row();
            }


            if entity_mut.contains::<SpriteRendererComponent>() {
                let mut removed = false;
                ui.horizontal(|ui|{
      
                    let size = ui.available_width() - DELETE_BUTTON_WIDTH;
                    ui.spacing_mut().item_spacing.x = 3.0;
                    ui.add_sized([size, 20.0], alice2d::ui::egui::Button::new("SpriteRenderer"));
                    if ui.button("delete").clicked() {
                        removed = true;
                        entity_mut.remove::<SpriteRendererComponent>();
                    };
                });
        
                if !removed {
                    ui.scope(|ui|{
                        let mut sprite = entity_mut.get_mut::<SpriteRendererComponent>().unwrap();
                        alice2d::ui::egui::Grid::new("my_color")
                            .min_row_height(20.0)
                            .spacing([43.0, 4.0])
                            .striped(true)
                            .show(ui, |ui| {
                                ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("color"));
                                let color = sprite.color;
                                let mut srgba = alice2d::ui::egui::Color32::from_rgba_premultiplied(
                                    color.0 .0, color.0 .1, color.0 .2, color.0 .3,
                                );
                                ui.color_edit_button_srgba(&mut srgba);
                                sprite.color = Rgba((srgba.r(), srgba.g(), srgba.b(), srgba.a()));
                            });
    
                        ui.end_row();
                        alice2d::ui::egui::Grid::new("my_texture")
                            .min_row_height(20.0)
                            .spacing([43.0, 4.0])
                            .striped(true)
                            .show(ui, |ui| {
                                ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("texture"));
                                if !sprite.path.is_empty() {
                                    if !layer.custom_image_texture.contains_key(&sprite.path) {
                                        if let Some(handle) = load_texture_to_egui(ui, &sprite.path) {
                                            layer.custom_image_texture
                                                .insert(sprite.path.clone(), handle);
                                        }
                                    }
                                    if let Some(handle) = layer.custom_image_texture.get(&sprite.path) {
                                        // Show the image:
                                        ui.image(handle, handle.size_vec2());
                                    }
                                }
                            });
                    });
                }
         
                ui.end_row();
            }

            if entity_mut.contains::<Rigidbody2DComponent>() {
                let mut removed = false;
                ui.horizontal(|ui|{
      
                    let size = ui.available_width() - DELETE_BUTTON_WIDTH;

                    ui.spacing_mut().item_spacing.x = 3.0;
                    ui.add_sized([size, 20.0], alice2d::ui::egui::Button::new("Rigidbody2D"));
                    if ui.button("delete").clicked() {
                        removed = true;
                        entity_mut.remove::<Rigidbody2DComponent>();
                    };
                });
          
                if !removed {
                    ui.scope(|ui|{
                        let mut rigidbody = entity_mut.get_mut::<Rigidbody2DComponent>().unwrap();
                        alice2d::ui::egui::Grid::new("rigidbody type")
                            .min_row_height(20.0)
                            .spacing([43.0, 4.0])
                            .striped(true)
                            .show(ui, |ui| {
                                ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("rigidbody type label"));
                                
                                alice2d::ui::egui::ComboBox::from_id_source("select rigidbody")
                                .selected_text(format!("{:?}", rigidbody.rb_type))
                                .show_ui(ui, |ui| {
                                ui.selectable_value(&mut rigidbody.rb_type, alice2d::physics2d::rapier2d::prelude::RigidBodyType::Dynamic, "Dynamic");
                                ui.selectable_value(&mut rigidbody.rb_type, alice2d::physics2d::rapier2d::prelude::RigidBodyType::Fixed, "Fixed");
                                ui.selectable_value(&mut rigidbody.rb_type, alice2d::physics2d::rapier2d::prelude::RigidBodyType::KinematicPositionBased, "KinematicPositionBased");
                                ui.selectable_value(&mut rigidbody.rb_type, alice2d::physics2d::rapier2d::prelude::RigidBodyType::KinematicVelocityBased, "KinematicVelocityBased");
                                    }
                                );
                              
                            
                            });
    
                        ui.end_row();
                        alice2d::ui::egui::Grid::new("mass")
                            .min_row_height(20.0)
                            .spacing([43.0, 4.0])
                            .striped(true)
                            .show(ui, |ui| {
                                ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("mass"));
                                ui.add(DragValue::new(&mut rigidbody.mass).speed(0.1))
                            });
                            ui.end_row();
    
                            alice2d::ui::egui::Grid::new("ccd")
                            .min_row_height(20.0)
                            .spacing([43.0, 4.0])
                            .striped(true)
                            .show(ui, |ui| {
                                ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("ccd"));
                                ui.add(alice2d::ui::egui::Checkbox::new(&mut rigidbody.ccd, ""))
                            });
                            ui.end_row();
                    });
                }
         
              
            }
            
            if entity_mut.contains::<Collider2DComponent>() {
                let mut removed = false;
                ui.horizontal(|ui|{
      
                    let size = ui.available_width() - DELETE_BUTTON_WIDTH;
                    ui.spacing_mut().item_spacing.x = 3.0;
                    ui.add_sized([size, 20.0], alice2d::ui::egui::Button::new("Collider2D"));
                    if ui.button("delete").clicked() {
                        removed = true;
                        entity_mut.remove::<Collider2DComponent>();
                    };
                });
             
                if !removed {
                    ui.scope(|ui|{
                        let mut collider2d = entity_mut.get_mut::<Collider2DComponent>().unwrap();
                        alice2d::ui::egui::Grid::new("restitution")
                            .min_row_height(20.0)
                            .spacing([43.0, 4.0])
                            .striped(true)
                            .show(ui, |ui| {
                                ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("restitution"));
                                ui.add(alice2d::ui::egui::Slider::new(&mut collider2d.restitution, 0.0..=1.0).show_value(false));
                            });
                            ui.end_row();
    
                            alice2d::ui::egui::Grid::new("friction")
                            .min_row_height(20.0)
                            .spacing([43.0, 4.0])
                            .striped(true)
                            .show(ui, |ui| {
                                ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("friction"));
                                ui.add(alice2d::ui::egui::Slider::new(&mut collider2d.friction, 0.0..=1.0).show_value(false));
                            });
                            ui.end_row();
                    });
                }
         

            }

            if entity_mut.contains::<ScriptComponent>() {
                let mut removed = false;
                ui.horizontal(|ui|{
      
                    let size = ui.available_width() - DELETE_BUTTON_WIDTH;
                    ui.spacing_mut().item_spacing.x = 3.0;
                    ui.add_sized([size, 20.0], alice2d::ui::egui::Button::new("Script"));
                    if ui.button("delete").clicked() {
                        removed = true;
                        entity_mut.remove::<ScriptComponent>();
                    };
                });
             
                if !removed {
                    ui.scope(|ui|{
                        let mut script = entity_mut.get_mut::<ScriptComponent>().unwrap();
                        alice2d::ui::egui::Grid::new("class Name")
                            .min_row_height(20.0)
                            .spacing([43.0, 4.0])
                            .striped(true)
                            .show(ui, |ui| {
                                ui.add_sized([LABEL_WIDTH, 30.0], alice2d::ui::egui::Label::new("class Name"));
                                ui.add(alice2d::ui::egui::Label::new(&script.class_name));
                            });
                            ui.end_row();
    
                    });
                }
         

            }
            
        }


        // let size = ui.available_width();
        
        if handle != scene.root {
            ui.horizontal(|ui|{
                ui.menu_button("Add Component", |ui: &mut Ui|{
                    Self::add_component(ui, layer,scene);
                });
            });
        }
      
    }

    fn add_component(ui: &mut egui::Ui,layer:&mut EditorLayer,scene:&mut Scene) {
        let handle = layer.select_entity.unwrap();
        let mut entity = Entity::new(handle);
            // Add a lot of widgets here.
            if !entity.has_component::<Rigidbody2DComponent>(&scene) {
                if ui.button("Rigidbody2DComponent").clicked() {
                    let rigidbody = Rigidbody2DComponent::new();
                    entity.add_component(scene, rigidbody);
                    ui.close_menu();
                }
            }

            if !entity.has_component::<Collider2DComponent>(&scene) {
                if ui.button("Collider2DComponent").clicked() {
                    let collider = Collider2DComponent::new();
                    entity.add_component(scene, collider);
                    ui.close_menu();
                }
            }

            if !entity.has_component::<CameraComponent>(&scene) {
                if ui.button("CameraComponent").clicked() {
                    let camera = CameraComponent::orthographic();
                    entity.add_component(scene, camera);
                    ui.close_menu();
                }
            }
           
            if !entity.has_component::<ScriptComponent>(&scene) {
                if ui.button("ScriptComponent").clicked() {
                    let script = ScriptComponent::new("assets/script/Player.js");
                    entity.add_component(scene, script);
                    ui.close_menu();
                }
            }
          
    }


}




pub fn load_image_from_path(path: &std::path::Path) -> Result<alice2d::ui::egui::ColorImage, image::ImageError> {
    let image = image::io::Reader::open(path)?.decode()?;
    let size = [image.width() as _, image.height() as _];
    let image_buffer = image.to_rgba8();
    let pixels = image_buffer.as_flat_samples();
    Ok(alice2d::ui::egui::ColorImage::from_rgba_unmultiplied(
        size,
        pixels.as_slice(),
    ))
}

fn draw_vec3_control(
    ui: &mut Ui,
    label: &str,
    value: &mut Vector3f,
    reset_value: f32,
    indent: f32,
) {
    alice2d::ui::egui::Grid::new(Id::new(label)).show(ui, |ui| {
        ui.style_mut().spacing.item_spacing.x = 20.0;

        ui.add_sized([LABEL_WIDTH, 40.0], alice2d::ui::egui::Label::new(label));

        ui.horizontal(|ui| {
      
            ui.style_mut().spacing.button_padding.x = 10.0;

            let color = alice2d::ui::egui::Color32::from_rgba_premultiplied(25, 29, 38, 255);
            set_bg(ui, color, color, color);

            ui.scope(|ui| {
                ui.style_mut().spacing.item_spacing.x = 0.0;

                ui.scope(|ui| {
                    ui.visuals_mut().override_text_color =
                        Some(alice2d::ui::egui::Color32::from_rgba_premultiplied(228, 152, 5, 255));

                    if ui.button("x").clicked() {
                        value.x = reset_value;
                    }
                });

                let color = alice2d::ui::egui::Color32::from_rgba_premultiplied(32, 36, 48, 255);
                set_bg(ui, color, color, color);

                ui.spacing_mut().interact_size.x = 60.0;
                ui.add(DragValue::new(&mut value.x).speed(0.1));
            });

            ui.scope(|ui| {
                ui.style_mut().spacing.item_spacing.x = 0.0;

                ui.scope(|ui| {
                    ui.visuals_mut().override_text_color =
                        Some(alice2d::ui::egui::Color32::from_rgba_premultiplied(33, 145, 232, 255));

                    if ui.button("y").clicked() {
                        value.y = reset_value;
                    }
                });
                let color = alice2d::ui::egui::Color32::from_rgba_premultiplied(32, 36, 48, 255);
                set_bg(ui, color, color, color);
                ui.spacing_mut().interact_size.x = 60.0;
                ui.add(DragValue::new(&mut value.y).speed(0.1));
            });

            ui.scope(|ui| {
                ui.style_mut().spacing.item_spacing.x = 0.0;
                ui.scope(|ui| {
                    ui.visuals_mut().override_text_color =
                        Some(alice2d::ui::egui::Color32::from_rgba_premultiplied(29, 139, 10, 255));

                    if ui.button("z").clicked() {
                        value.z = reset_value;
                    }
                });
                let color = alice2d::ui::egui::Color32::from_rgba_premultiplied(32, 36, 48, 255);
                set_bg(ui, color, color, color);
                ui.spacing_mut().interact_size.x = 60.0;
                ui.add(DragValue::new(&mut value.z).speed(0.1));
            });
        });
        ui.end_row();
    });
}




fn set_bg(
    ui: &mut Ui,
    bg: impl Into<Color32>,
    hover: impl Into<Color32>,
    active: impl Into<Color32>,
) {
    ui.visuals_mut().widgets.inactive.bg_fill = bg.into();
    ui.visuals_mut().widgets.hovered.bg_fill = hover.into();
    ui.visuals_mut().widgets.active.bg_fill = active.into();
}

fn clear_outline_and_rounding(ui: &mut Ui) {
    ui.visuals_mut().widgets.inactive.bg_stroke = Stroke::none();
    ui.visuals_mut().widgets.hovered.bg_stroke = Stroke::none();
    ui.visuals_mut().widgets.active.bg_stroke = Stroke::none();

    ui.visuals_mut().widgets.inactive.rounding = Rounding::none();
    ui.visuals_mut().widgets.hovered.rounding = Rounding::none();
    ui.visuals_mut().widgets.active.rounding = Rounding::none();
}

pub fn load_texture_to_egui(ui: &mut Ui, path: impl AsRef<str>) -> Option<TextureHandle> {
    let c = load_image_from_path(std::path::Path::new(path.as_ref()));
    match c {
        Ok(image) => {
            let texture_handle =
                ui.ctx()
                    .load_texture(path.as_ref(), image, alice2d::ui::egui::TextureFilter::Linear);
            Some(texture_handle)
        }
        Err(e) => None,
    }
}


